﻿using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;

namespace RabbitMQDemo.Consumer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Start consumers");

            var connFactory = new ConnectionFactory
            {
                HostName = "106.53.127.56",
                Port = 5672,
                UserName = "rabbitmqdemo",
                Password = "rabbitmqdemo@test",
                VirtualHost = "rabbitmqdemo",
            };
            using (var conn = connFactory.CreateConnection())
            {
                using (var channel = conn.CreateModel())
                {
                    //模拟外部存储服务
                    Dictionary<string, int> MessageRetryCounts = new Dictionary<string, int>();

                    var queueName = "storageretrycount_queue";
                    channel.QueueDeclare(queue: queueName, durable: false, exclusive: false, autoDelete: false, arguments: null);
                    channel.BasicQos(0, 5, false);

                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += (model, ea) =>
                    {
                        var message = ea.Body;
                        Console.WriteLine("接收到信息为:" + Encoding.UTF8.GetString(message.ToArray()));

                        if (Encoding.UTF8.GetString(message.ToArray()).Contains("50"))
                        {
                            var maxRetryCount = 3;
                            Console.WriteLine("拒收");

                            //重试次数判断
                            var existRetryRecord = MessageRetryCounts.ContainsKey(ea.BasicProperties.MessageId);
                            if (!existRetryRecord)
                            {
                                //重入队列，继续重试
                                MessageRetryCounts.Add(ea.BasicProperties.MessageId, 1);
                                ((EventingBasicConsumer)model).Model.BasicReject(ea.DeliveryTag, requeue: true);
                                return;
                            }

                            if (MessageRetryCounts[ea.BasicProperties.MessageId] < maxRetryCount)
                            {
                                //重入队列，继续重试
                                MessageRetryCounts[ea.BasicProperties.MessageId] = MessageRetryCounts[ea.BasicProperties.MessageId] + 1;
                                ((EventingBasicConsumer)model).Model.BasicReject(ea.DeliveryTag, requeue: true);
                                return;
                            }

                            //到达最大次数，后续不再重试消息
                            ((EventingBasicConsumer)model).Model.BasicReject(ea.DeliveryTag, requeue: false);
                            return;
                        }

                        ((EventingBasicConsumer)model).Model.BasicAck(ea.DeliveryTag, multiple: false);
                    };

                    channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer);
                    Console.ReadKey();
                }
            }
        }
    }
}